#include "../../AI.h"


AI::AI(int _difficulty_level, int _player)
{
	difficulty_level = _difficulty_level;
	player = _player;
}

/*********************************************************
 AI::AnalyzeMove()
 ********************************************************/
 int AI::AnalyzeMove(Checkers &yourTurn)
{
	Board *move = yourTurn.GetBoard(); // Gets the board
	
	int score;
	
	if(player==CHECKERS_PLAYER2)
		score = move->GetPlayer2PieceCount() - move->GetPlayer1PieceCount(); // calculates the score
	else
		score = move->GetPlayer1PieceCount() - move->GetPlayer2PieceCount();

	return score;
}

/*********************************************************
  AI::Alpha_Beta()
 ********************************************************/
int AI::Alpha_Beta(bool maxNode, int alpha, int beta, int currentDepth, Checkers &yourTurn, Board currentState)
{
	yourTurn.SetMovesWithNoCapture(nonCaptures);

	if (currentDepth == difficulty_level) // if at the bottom of the tree
		return AnalyzeMove(yourTurn); // evaluate move 
	
	if (player == CHECKERS_PLAYER2) // if AI is Player 2 
	{
		if (yourTurn.GetStatus() == STATUS_PLAYER1_WON) // if this move means player 1 wins
			return ALPHA; // this is the worst move that can be made

		if (yourTurn.GetStatus() == STATUS_PLAYER2_WON) // if this move means player 2 wins
			return BETA; // this is the best move
	}

	else // AI is Player 1
	{
		if (yourTurn.GetStatus() == STATUS_PLAYER2_WON) // if this move means player 2 wins
			return ALPHA; // this is the worst move that can be made

		if (yourTurn.GetStatus() == STATUS_PLAYER1_WON) // if this move means player 1 wins
			return BETA; // this is the best move
	}

	vector<MoveData*> moves; // an empty vector for the moves
	int maxMoves = yourTurn.GetLegalMoves(moves); // gets the legal moves for this turn 
	int score; // the value of this node
	int diw;

	Board *PnextMove;// the board after this move is made
	
	if (maxNode) 
	{
		for (int i = 0; i < maxMoves; i++) 
		{
			// Try the move

			diw = yourTurn.Move(moves[i]->StartX(),moves[i]->StartY(),moves[i]->EndX(),moves[i]->EndY());
			PnextMove = yourTurn.GetBoard(); // gets the next move

			
			/*cout << nextMove;
			cout << "move try " << i << "\n\n";*/

			if(diw == MOVE_OK)
				score = Alpha_Beta(false,alpha,beta,currentDepth+1,yourTurn,*PnextMove); // move deeper down the tree

			else if(diw == MOVE_OK_CAPTURE)
				score = Alpha_Beta(maxNode,alpha,beta,currentDepth,yourTurn,*PnextMove);

			if(score > alpha) // if the score is less than alpha
				alpha = score; // score becomes new alpha

			if(alpha >= beta) // if alpha is less than or equal to beta
			{
				yourTurn.SetBoard(currentState); //reset the game board

				if(diw == MOVE_OK)
				 yourTurn.ChangePlayerTurn(); // reset the turn

				return alpha;  // cut off
				
			}

			 yourTurn.SetBoard(currentState); //reset the game board
			 
			 if(diw == MOVE_OK)
				 yourTurn.ChangePlayerTurn(); // reset the turn
		}
		return alpha; 
	}

	else
	{
		for (int i = 0; i < maxMoves; i++)
		{
			// Try the move
			diw = yourTurn.Move(moves[i]->StartX(),moves[i]->StartY(),moves[i]->EndX(),moves[i]->EndY());

			PnextMove = yourTurn.GetBoard();	
			
			/*cout << nextMove;
			cout << "move try " << i << "\n\n";*/
			
			if(diw == MOVE_OK)
				score = Alpha_Beta(true,alpha,beta,currentDepth+1,yourTurn,*PnextMove); // move deeper down the tree

			else if(diw == MOVE_OK_CAPTURE)
				score = Alpha_Beta(maxNode,alpha,beta,currentDepth,yourTurn,*PnextMove);

			if(score > alpha) // if the score is less than alpha
				beta = score; // score becomes new alpha

			if(alpha >= beta) // if alpha is less than or equal to beta
			{
				yourTurn.SetBoard(currentState); //reset the game board
				
				if(diw == MOVE_OK)
				 yourTurn.ChangePlayerTurn(); // reset the turn

				return beta;  // cut off
			}

			 yourTurn.SetBoard(currentState); //reset the game board
			 
			 if(diw == MOVE_OK)
				 yourTurn.ChangePlayerTurn(); // reset the turn
		}
	return beta;
	}
}

/*********************************************************
 * AI::FinalMove()
 ********************************************************/

int AI::FinalMove(Checkers &yourTurn, Board currentState)
{
	
	vector<MoveData*> moves; // an empty vector for the moves
	int maxMoves = yourTurn.GetLegalMoves(moves);  
	int score; // the value of this node
	int bestScore = ALPHA;
	int bestMove = 0;	
	int diw;
	nonCaptures = yourTurn.GetMovesWithNoCapture();

	Board *PnextMove;// the board after this move is made
		
	for (int i = 0; i < maxMoves; i++)// gets the legal moves for this turn
	{
		// Try the move
		diw = yourTurn.Move(moves[i]->StartX(),moves[i]->StartY(),moves[i]->EndX(),moves[i]->EndY());

		PnextMove = yourTurn.GetBoard();			

		if(diw == MOVE_OK)
				score = Alpha_Beta(false,ALPHA,BETA,0,yourTurn,*PnextMove); // move deeper down the tree

			else if(diw == MOVE_OK_CAPTURE)
				score = Alpha_Beta(true,ALPHA,BETA,0,yourTurn,*PnextMove);
		
		if (score > bestScore)
		{
			bestScore = score;
			bestMove = i;
		}

		yourTurn.SetBoard(currentState); //reset the game board
		
		if(diw == MOVE_OK)
			yourTurn.ChangePlayerTurn(); // reset the turn

	}

	yourTurn.SetMovesWithNoCapture(nonCaptures);

	// execute the best move
	diw = yourTurn.Move(moves[bestMove]->StartX(),
				  moves[bestMove]->StartY(),
				  moves[bestMove]->EndX(),
				  moves[bestMove]->EndY());

	return diw;
}


